package com.jt.AOP;


import jdk.internal.org.objectweb.asm.commons.TryCatchBlockSorter;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.xml.transform.Result;

//1、AOP需要被Spring容器管理
@Component
//2、标识该类为AOP切面
@Aspect
public class SpringAOP {
    /*切入点表达式练习：
    1、within(com.jt.*.DeptServiceImpl)  一级包下的类
    2、within(com.jt..*.DeptserviceImpl) ..代表多级包下的类
    3、within(com.jt..*) 包下的所有类
    * */
    //3、定义before类
    //@Before("bean(deptServiceImpl)")
    //@Before("within(com.jt.*.DeptServiceImpl)")
    //@Before("execution(* com.jt..*.DeptServiceImpl.add*())")
   // @Before("@annotation(com.jt.anno.Cache)")
    //@Before("within(com.jt.Service.DeptServiceImpl)")
    public void before(JoinPoint joinPoint){
        System.out.println("获取目标对象的类型："+joinPoint.getTarget().getClass());
        System.out.println("获取目标对象类名"+joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("获取目标对象方法名"+joinPoint.getSignature().getName());
        System.out.println("我是before通知");
    }

    //定义切入点表达式
   @Pointcut("@annotation(com.jt.anno.Cache)")
    public void pointcut(){

    }
   //记录方法返回值

    //@AfterReturning(pointcut = "pointcut()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        System.out.println("我是afterReturning通知");
        System.out.println("用户的返回值结果："+result);
    }

    //@AfterThrowing(pointcut = "pointcut()",throwing = "e")
     public void afterThrowing( Exception e){
        System.out.println("获取异常通知"+e.getMessage());
        System.out.println("获取异常的类型："+e.getClass());
        System.out.println("我是异常的通知");
    }
   // @After("pointcut()")
    public void after(){
        System.out.println("我是after通知");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
       Object result=null;
        System.out.println("环绕通知开始");
        //执行下一个通知
        try {
            long start = System.currentTimeMillis();
            result=joinPoint.proceed();
            Long end=System.currentTimeMillis();
            System.out.println("耗时："+(end-start));
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }
        System.out.println("环绕通知结束");
        return result;
  }

}
